﻿using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32;


namespace ShellLib
{
    public static class Imports
    {
        public delegate Int32 BrowseCallbackProc(IntPtr hwnd, UInt32 uMsg, Int32 lParam, Int32 lpData);

        public static Int16 GetHResultCode(Int32 hr)
        {
            hr = hr & 0x0000ffff;
            return (Int16)hr;
        }

        #region Enums

        public enum CSIDL
        {
            #region CSDL Flags

            /** These flags can be used in conjunction with the enum constants to enforce certain behaiviors **/
            /// <summary>
            /// Combine this CSIDL with any of the following CSIDLs to force the creation of the associated folder.
            /// </summary>
            CSIDL_FLAG_CREATE = (0x8000),

            /// <summary>
            /// Combine with another CSIDL constant, except for CSIDL_FLAG_CREATE, to return an unverified folder path with no attempt to create or initialize the folder.
            /// </summary>
            CSIDL_FLAG_DONT_VERIFY = 0x4000,

            /// <summary>
            /// Combine with another CSIDL constant to ensure the expansion of environment variables
            /// </summary>
            CSIDL_FLAG_DONT_UNEXPAND = 0x2000,

            /// <summary>
            /// Combine with another CSIDL constant to ensure the retrieval of the true system path for the folder, free of any aliased placeholders
            /// </summary>
            CSIDL_FLAG_NO_ALIAS = 0x1000,

            CSIDL_FLAG_PER_USER_INIT = 0x0800,

            #endregion

            /// <summary>
            /// A mask for any valid CSIDL flag value
            /// </summary>
            CSIDL_FLAG_MASK = 0xFF00,

            /// <summary>
            /// The file system directory that is used to store administrative tools for an individual user. The Microsoft Management Console (MMC) will save customized consoles to this directory, and it will roam with the user.
            /// </summary>
            CSIDL_ADMINTOOLS = (0x0030),

            /// <summary>
            /// The file system directory that corresponds to the user's nonlocalized Startup program group. This value is recognized in Windows Vista for backward compatibility, but the folder itself no longer exists.
            /// </summary>
            CSIDL_ALTSTARTUP = (0x001d),

            /// <summary>
            /// The file system directory that serves as a common repository for application-specific data. A typical path is C:\Documents and Settings\username\Application Data. This CSIDL is supported by the redistributable Shfolder.dll for systems that do not have the Microsoft Internet Explorer 4.0 integrated Shell installed.
            /// </summary>
            CSIDL_APPDATA = (0x001a),

            /// <summary>
            /// The virtual folder that contains the objects in the user's Recycle Bin
            /// </summary>
            CSIDL_BITBUCKET = (0x000a),

            /// <summary>
            ///  The file system directory that acts as a staging area for files waiting to be written to a CD. A typical path is C:\Documents and Settings\username\Local Settings\Application Data\Microsoft\CD Burning.
            /// </summary>
            CSIDL_CDBURN_AREA = (0x003b),

            /// <summary>
            /// The file system directory that contains administrative tools for all users of the computer.
            /// </summary>
            CSIDL_COMMON_ADMINTOOLS = (0x002f),

            /// <summary>
            /// The file system directory that corresponds to the nonlocalized Startup program group for all users. Valid only for Microsoft Windows NT systems. This value is recognized in Windows Vista for backward compatibility, but the folder itself no longer exists.
            /// </summary>
            CSIDL_COMMON_ALTSTARTUP = (0x001e),

            /// <summary>
            /// The file system directory that contains application data for all users. A typical path is C:\Documents and Settings\All Users\Application Data. This folder is used for application data that is not user specific.
            /// </summary>
            CSIDL_COMMON_APPDATA = (0x0023),


            /// <summary>
            /// The file system directory that contains files and folders that appear on the desktop for all users.
            /// </summary>
            CSIDL_COMMON_DESKTOPDIRECTORY = (0x0019),

            /// <summary>
            /// The file system directory that contains documents that are common to all users
            /// </summary>
            CSIDL_COMMON_DOCUMENTS = (0x002e),
            /// <summary>
            /// The file system directory that serves as a common repository for favorite items common to all users. Valid only for Windows NT systems
            /// </summary>
            CSIDL_COMMON_FAVORITES = (0x001f),
            /// <summary>
            /// The file system directory that serves as a repository for music files common to all users.
            /// </summary>
            CSIDL_COMMON_MUSIC = (0x0035),

            /// <summary>
            /// This value is recognized in Windows Vista for backward compatibility, but the folder itself is no longer used
            /// </summary>
            CSIDL_COMMON_OEM_LINKS = (0x003a),

            /// <summary>
            /// The file system directory that serves as a repository for image files common to all users
            /// </summary>
            CSIDL_COMMON_PICTURES = (0x0036),

            /// <summary>
            /// The file system directory that contains the directories for the common program groups that appear on the Start menu for all users
            /// </summary>
            CSIDL_COMMON_PROGRAMS = (0x0017),

            /// <summary>
            /// The file system directory that contains the programs and folders that appear on the Start menu for all users
            /// </summary>
            CSIDL_COMMON_STARTMENU = (0x0016),

            /// <summary>
            /// The file system directory that contains the programs that appear in the Startup folder for all users
            /// </summary>
            CSIDL_COMMON_STARTUP = (0x0018),

            /// <summary>
            /// The file system directory that contains the templates that are available to all users
            /// </summary>
            CSIDL_COMMON_TEMPLATES = (0x002d),

            /// <summary>
            /// The folder that represents other computers in your workgroup
            /// </summary>
            CSIDL_COMPUTERSNEARME = 0x003d,

            /// <summary>
            /// The virtual folder that represents Network Connections, that contains network and dial-up connections
            /// </summary>
            CSIDL_CONNECTIONS = 0x0031,

            /// <summary>
            /// The file system directory that serves as a repository for video files common to all users
            /// </summary>
            CSIDL_COMMON_VIDEO = (0x0037),

            /// <summary>
            /// The virtual folder that contains icons for the Control Panel applications
            /// </summary>
            CSIDL_CONTROLS = (0x0003),

            /// <summary>
            /// The file system directory that serves as a common repository for Internet cookies
            /// </summary>
            CSIDL_COOKIES = (0x0021),

            /// <summary>
            /// The virtual folder that represents the Windows desktop, the root of the namespace
            /// </summary>
            CSIDL_DESKTOP = (0x0000),

            /// <summary>
            /// he file system directory used to physically store file objects on the desktop (not to be confused with the desktop folder itself). A typical path is C:\Documents and Settings\username\Desktop.
            /// </summary>
            CSIDL_DESKTOPDIRECTORY = (0x0010),

            /// <summary>
            /// he virtual folder that represents My Computer, containing everything on the local computer: storage devices, printers, and Control Panel. The folder can also contain mapped network drives
            /// </summary>
            CSIDL_DRIVES = (0x0011),

            /// <summary>
            /// The file system directory that serves as a common repository for the user's favorite items
            /// </summary>
            CSIDL_FAVORITES = (0x0006),

            /// <summary>
            /// A virtual folder that contains fonts
            /// </summary>
            CSIDL_FONTS = (0x0014),

            /// <summary>
            /// The file system directory that serves as a common repository for Internet history items
            /// </summary>
            CSIDL_HISTORY = (0x0022),

            /// <summary>
            /// A virtual folder for Internet Explorer
            /// </summary>
            CSIDL_INTERNET = (0x0001),

            /// <summary>
            /// he file system directory that serves as a common repository for temporary Internet files. A typical path is C:\Documents and Settings\username\Local Settings\Temporary Internet Files.
            /// </summary>
            CSIDL_INTERNET_CACHE = (0x0020),

            /// <summary>
            /// The file system directory that serves as a data repository for local (nonroaming) applications
            /// </summary>
            CSIDL_LOCAL_APPDATA = (0x001c),

            /// <summary>
            /// The virtual folder that represents the My Documents desktop item. This value is equivalent to CSIDL_PERSONAL
            /// </summary>
            CSIDL_MYDOCUMENTS = (0x000c),

            /// <summary>
            /// The file system directory that serves as a common repository for music files
            /// </summary>
            CSIDL_MYMUSIC = (0x000d),

            /// <summary>
            /// The file system directory that serves as a common repository for image files
            /// </summary>
            CSIDL_MYPICTURES = (0x0027),

            /// <summary>
            /// The file system directory that serves as a common repository for video files
            /// </summary>
            CSIDL_MYVIDEO = (0x000e),

            /// <summary>
            /// A file system directory that contains the link objects that may exist in the My Network Places virtual folder. It is not the same as CSIDL_NETWORK, which represents the network namespace root
            /// </summary>
            CSIDL_NETHOOD = (0x0013),

            /// <summary>
            /// A virtual folder that represents Network Neighborhood, the root of the network namespace hierarchy
            /// </summary>
            CSIDL_NETWORK = (0x0012),

            /// <summary>
            /// The virtual folder that represents the My Documents desktop item. This is equivalent to CSIDL_MYDOCUMENTS
            /// </summary>
            CSIDL_PERSONAL = (0x0005),

            /// <summary>
            /// he virtual folder that contains installed printers
            /// </summary>
            CSIDL_PRINTERS = (0x0004),

            /// <summary>
            /// The file system directory that contains the link objects that can exist in the Printers virtual folder
            /// </summary>
            CSIDL_PRINTHOOD = (0x001b),

            /// <summary>
            /// The user's profile folder. A typical path is C:\Users\username. Applications should not create files or folders at this level; they should put their data under the locations referred to by CSIDL_APPDATA or CSIDL_LOCAL_APPDATA. However, if you are creating a new Known Folder the profile root refered to by CSIDL_PROFILE is appropriate.
            /// </summary>
            CSIDL_PROFILE = (0x0028),

            /// <summary>
            /// 
            /// </summary>
            CSIDL_PROFILES = (0x003e),

            /// <summary>
            ///  The Program Files folder
            /// </summary>
            CSIDL_PROGRAM_FILES = (0x0026),

            /// <summary>
            /// A folder for components that are shared across applications. A typical path is C:\Program Files\Common
            /// </summary>
            CSIDL_PROGRAM_FILES_COMMON = (0x002b),

            /// <summary>
            /// The file system directory that contains the user's program groups (which are themselves file system directories). A typical path is C:\Documents and Settings\username\Start Menu\Programs.
            /// </summary>
            CSIDL_PROGRAMS = (0x0002),

            /// <summary>
            /// The file system directory that contains shortcuts to the user's most recently used documents
            /// </summary>
            CSIDL_RECENT = (0x0008),

            /// <summary>
            /// Windows Vista. The file system directory that contains resource data. A typical path is C:\Windows\Resources
            /// </summary>
            CSIDL_RESOURCES = 0x0038,

            CSIDL_RESOURCES_LOCALIZED = 0x0039,

            /// <summary>
            /// The file system directory that contains Send To menu items
            /// </summary>
            CSIDL_SENDTO = (0x0009),

            /// <summary>
            /// The file system directory that contains Start menu items
            /// </summary>
            CSIDL_STARTMENU = (0x000b),

            /// <summary>
            /// The file system directory that corresponds to the user's Startup program group. The system starts these programs whenever any user logs onto Windows NT or starts Windows 95
            /// </summary>
            CSIDL_STARTUP = (0x0007),

            /// <summary>
            /// The Windows System folder. A typical path is C:\Windows\System32
            /// </summary>
            CSIDL_SYSTEM = (0x0025),

            /// <summary>
            /// The file system directory that serves as a common repository for document templates
            /// </summary>
            CSIDL_TEMPLATES = (0x0015),

            /// <summary>
            /// he Windows directory or SYSROOT. This corresponds to the %windir% or %SYSTEMROOT% environment variables. A typical path is C:\Windows.
            /// </summary>
            CSIDL_WINDOWS = (0x0024),

        }

        public enum SHGFP_TYPE
        {
            /// <summary>
            /// current value for user, verify it exists
            /// </summary>
            SHGFP_TYPE_CURRENT = 0,

            /// <summary>
            /// default value, may not exist
            /// </summary>
            SHGFP_TYPE_DEFAULT = 1
        }

        public enum SFGAO : uint
        {
            SFGAO_CANCOPY = 0x00000001,	// Objects can be copied    
            SFGAO_CANMOVE = 0x00000002,	// Objects can be moved     
            SFGAO_CANLINK = 0x00000004,	// Objects can be linked    
            SFGAO_STORAGE = 0x00000008,   // supports BindToObject(IID_IStorage)
            SFGAO_CANRENAME = 0x00000010,   // Objects can be renamed
            SFGAO_CANDELETE = 0x00000020,   // Objects can be deleted
            SFGAO_HASPROPSHEET = 0x00000040,   // Objects have property sheets
            SFGAO_DROPTARGET = 0x00000100,   // Objects are drop target
            SFGAO_CAPABILITYMASK = 0x00000177,	// This flag is a mask for the capability flags.
            SFGAO_ENCRYPTED = 0x00002000,   // object is encrypted (use alt color)
            SFGAO_ISSLOW = 0x00004000,   // 'slow' object
            SFGAO_GHOSTED = 0x00008000,   // ghosted icon
            SFGAO_LINK = 0x00010000,   // Shortcut (link)
            SFGAO_SHARE = 0x00020000,   // shared
            SFGAO_READONLY = 0x00040000,   // read-only
            SFGAO_HIDDEN = 0x00080000,   // hidden object
            SFGAO_DISPLAYATTRMASK = 0x000FC000,	// This flag is a mask for the display attributes.
            SFGAO_FILESYSANCESTOR = 0x10000000,   // may contain children with SFGAO_FILESYSTEM
            SFGAO_FOLDER = 0x20000000,   // support BindToObject(IID_IShellFolder)
            SFGAO_FILESYSTEM = 0x40000000,   // is a win32 file system object (file/folder/root)
            SFGAO_HASSUBFOLDER = 0x80000000,   // may contain children with SFGAO_FOLDER
            SFGAO_CONTENTSMASK = 0x80000000,	// This flag is a mask for the contents attributes.
            SFGAO_VALIDATE = 0x01000000,   // invalidate cached information
            SFGAO_REMOVABLE = 0x02000000,   // is this removeable media?
            SFGAO_COMPRESSED = 0x04000000,   // Object is compressed (use alt color)
            SFGAO_BROWSABLE = 0x08000000,   // supports IShellFolder, but only implements CreateViewObject() (non-folder view)
            SFGAO_NONENUMERATED = 0x00100000,   // is a non-enumerated object
            SFGAO_NEWCONTENT = 0x00200000,   // should show bold in explorer tree
            SFGAO_CANMONIKER = 0x00400000,   // defunct
            SFGAO_HASSTORAGE = 0x00400000,   // defunct
            SFGAO_STREAM = 0x00400000,   // supports BindToObject(IID_IStream)
            SFGAO_STORAGEANCESTOR = 0x00800000,   // may contain children with SFGAO_STORAGE or SFGAO_STREAM
            SFGAO_STORAGECAPMASK = 0x70C50008    // for determining storage capabilities, ie for open/save semantics

        }


        /// <summary>
        /// these values are from PInvoke.net
        /// </summary>
        public enum STRRET_TYPE
        {
            /// <summary>
            /// Use STRRET.pOleStr
            /// </summary>
            STRRET_WSTR = 0x0000,

            /// <summary>
            ///  Use STRRET.uOffset to Ansi
            /// </summary>
            STRRET_OFFSET = 0x0001,

            /// <summary>
            /// Use STRRET.cStr
            /// </summary>
            STRRET_CSTR = 0x0002
        }

        public enum PrinterActions
        {
            /// <summary>
            /// Open the printer specified by lpBuf1. The lpBuf2 parameter is ignored
            /// </summary>
            PRINTACTION_OPEN = 0x0,

            /// <summary>
            ///  Display the property pages for the printer specified by lpBuf1. The lpBuf2 parameter can be NULL or can name a specific property sheet to display, either by name or number.
            /// </summary>
            PRINTACTION_PROPERTIES = 0x1,

            /// <summary>
            /// Install the network printer specified by lpBuf1. The lpBuf2 parameter is ignored
            /// </summary>
            PRINTACTION_NETINSTALL = 0x2,

            /// <summary>
            /// Create a shortcut to the network printer specified by lpBuf1. The lpBuf2 parameter specifies the drive and path of the folder in which to create the shortcut
            /// </summary>
            PRINTACTION_NETINSTALLLINK = 0x3,

            /// <summary>
            /// Print a test page on the printer specified by lpBuf1. The lpBuf2 parameter is ignored.
            /// </summary>
            PRINTACTION_TESTPAGE = 0x4,

            /// <summary>
            /// Open the network printer specified by lpBuf1. The lpBuf2 parameter is ignored
            /// </summary>
            PRINTACTION_OPENNETPRN = 0x5,

            /// <summary>
            /// Display the default document properties for the printer specified by lpBuf1. The lpBuf2 parameter is ignored
            /// </summary>
            PRINTACTION_DOCUMENTDEFAULTS = 0x6,

            /// <summary>
            /// Display the properties for the printer server specified by lpBuf1. The lpBuf2 parameter is ignored
            /// </summary>
            PRINTACTION_SERVERPROPERTIES = 0x7
        }

        public enum AppBarMessages
        {
            /// <summary>
            /// Registers a new appbar and specifies the message identifier
            /// that the system should use to send notification messages to 
            /// the appbar. 
            /// </summary>
            ABM_NEW = 0x00000000,
            /// <summary>
            /// Unregisters an appbar, removing the bar from the system's 
            /// internal list.
            /// </summary>
            ABM_REMOVE = 0x00000001,
            /// <summary>
            /// Requests a size and screen position for an appbar.
            /// </summary>
            ABM_QUERYPOS = 0x00000002,
            /// <summary>
            /// Sets the size and screen position of an appbar. 
            /// </summary>
            ABM_SETPOS = 0x00000003,
            /// <summary>
            /// Retrieves the autohide and always-on-top states of the 
            /// Microsoft® Windows® taskbar. 
            /// </summary>
            ABM_GETSTATE = 0x00000004,
            /// <summary>
            /// Retrieves the bounding rectangle of the Windows taskbar. 
            /// </summary>
            ABM_GETTASKBARPOS = 0x00000005,
            /// <summary>
            /// Notifies the system that an appbar has been activated. 
            /// </summary>
            ABM_ACTIVATE = 0x00000006,
            /// <summary>
            /// Retrieves the handle to the autohide appbar associated with
            /// a particular edge of the screen. 
            /// </summary>
            ABM_GETAUTOHIDEBAR = 0x00000007,
            /// <summary>
            /// Registers or unregisters an autohide appbar for an edge of 
            /// the screen. 
            /// </summary>
            ABM_SETAUTOHIDEBAR = 0x00000008,
            /// <summary>
            /// Notifies the system when an appbar's position has changed. 
            /// </summary>
            ABM_WINDOWPOSCHANGED = 0x00000009,
            /// <summary>
            /// Sets the state of the appbar's autohide and always-on-top 
            /// attributes.
            /// </summary>
            ABM_SETSTATE = 0x0000000a
        }

        #endregion

        #region File Functions

        /// <summary>
        /// Retrieves information about an object in the file system, such as a file, folder, directory,
        ///  or drive root.
        /// </summary>
        /// <param name="pszPath"> A pointer to a null-terminated string of maximum length MAX_PATH that
        ///  contains the 
        /// path and file name</param>
        /// <param name="dwFileAttributes">A combination of one or more file attribute flags</param>
        /// <param name="psfi">[out] The address of a SHFILEINFO structure to receive the file information.</param>
        /// <param name="cbSizeFileInfo">[in] The size, in bytes, of the SHFILEINFO structure pointed to 
        /// by the psfi parameter.</param>
        /// <param name="uFlags">[in] The flags that specify the file information to retrieve.</param>
        /// <returns></returns>
        /// <seealso cref="http://msdn.microsoft.com/en-us/library/bb762179(VS.85).aspx"/>
        [DllImport("shell32.dll")]
        public static extern IntPtr SHGetFileInfo(
            string pszPath,
            uint dwFileAttributes,
            ref SHFILEINFO psfi,
            uint cbSizeFileInfo,
            uint uFlags);

        /// <summary>
        /// Takes the CSIDL of a folder and returns the pathname.
        /// </summary>
        /// <param name="hwndOwner">Handle to an owner window.</param>
        /// <param name="nFolder">A CSIDL value that identifies the folder whose path is to be retrieved.</param>
        /// <param name="hToken">An access token that can be used to represent a particular user.</param>
        /// <param name="dwFlags">Flags to specify which path is to be returned. It is used for cases where
        /// the folder associated with a CSIDL may be moved or renamed by the user</param>
        /// <param name="pszPath">Pointer to a null-terminated string which will receive the path.</param>
        /// <returns>Pathname</returns>
        /// <remarks>Depreciated! As of Windows Vista, this function is merely a wrapper for SHGetKnownFolderPath</remarks>
        [DllImport("shell32.dll")]
        public static extern int SHGetFolderPath(
            IntPtr hwndOwner,
            int nFolder,
            IntPtr hToken,
            uint dwFlags,
            [Out] StringBuilder pszPath);


        /// <summary>
        /// Retrieves the full path of a known folder identified by the folder's KNOWNFOLDERID
        /// </summary>
        /// <param name="rfid">A reference to the KNOWNFOLDERID that identifies the folder.</param>
        /// <param name="dwFlags">Flags that specify special retrieval options. 
        /// This value can be 0; otherwise, one or more of the KNOWN_FOLDER_FLAG values</param>
        /// <param name="hToken"> An access token that represents a particular user.
        ///  If this parameter is NULL, which is the most common usage, the function requests the
        /// known folder for the current user</param>
        /// <param name="pszPath">the path of the known folder</param>
        /// <returns>Returns S_OK if successful, or an error value otherwise</returns>
        /// <seealso cref="http://msdn.microsoft.com/en-us/library/bb762584(VS.85).aspx" for KNOWNFOLDERID GUIDs/>
        [DllImport("shell32.dll")]
        public static extern int SHGetKnownFolderPath(
            [MarshalAs(UnmanagedType.LPStruct)] 
            Guid rfid,
            uint dwFlags,
            IntPtr hToken,
            out IntPtr pszPath);

        /// <summary>
        /// Retrieves the IShellFolder interface for the desktop folder, which is the root of the Shell's namespace.
        /// </summary>
        /// <param name="ppshf">Address that receives an IShellFolder interface pointer for the desktop folder.</param>
        /// <returns></returns> 
        [DllImport("shell32.dll")]
        public static extern Int32 SHGetDesktopFolder(out IntPtr ppshf);

        /// <summary>
        /// Copies, moves, renames, or deletes a file system object
        /// </summary>
        /// <param name="lpFileOp">A pointer to an SHFILEOPSTRUCT structure that contains information
        ///  this function needs to carry out the specified operation</param>
        /// <returns>Returns zero if successful; otherwise nonzero</returns>
        /// <remarks>This function has been replaced in Windows Vista by IFileOperation</remarks>
        [DllImport("shell32.dll", CharSet = CharSet.Unicode)]
        public static extern Int32 SHFileOperation(ref SHFILEINFO.SHFILEOPSTRUCT lpFileOp);

        #endregion

        #region General Shell

        /// <summary>
        /// Retrieves a pointer to the Shell's IMalloc interface.
        /// </summary>
        /// <param name="hObject">Address of a pointer that receives the Shell's IMalloc interface pointer.</param>
        /// <returns>pointer to the Shell's IMalloc interface</returns>
        [DllImport("shell32.dll")]
        public static extern Int32 SHGetMalloc(out IntPtr hObject);

        /// <summary>
        /// Retrieves the path of a folder as an PIDL.
        /// </summary>
        /// <param name="hwndOwner">Handle to the owner window.</param>
        /// <param name="nFolder">A CSIDL value that identifies the folder to be located.</param>
        /// <param name="hToken">Token that can be used to represent a particular user.</param>
        /// <param name="dwReserved">Reserved.</param>
        /// <param name="ppidl">Address of a pointer to an item identifier list structure
        /// specifying the folder's location relative to the root of the namespace (the desktop). </param>
        /// <returns></returns>
        [DllImport("shell32.dll")]
        public static extern Int32 SHGetFolderLocation(
            IntPtr hwndOwner,
            Int32 nFolder,
            IntPtr hToken,
            UInt32 dwReserved,
            out IntPtr ppidl);

        /// <summary>
        ///  Converts an item identifier list to a file system path.
        /// </summary>
        /// <param name="pidl">Address of an item identifier list that specifies a file or directory location
        /// relative to the root of the namespace (the desktop).</param>
        /// <param name="pszPath">Address of a buffer to receive the file system path.</param>
        /// <returns></returns>
        [DllImport("shell32.dll")]
        public static extern Int32 SHGetPathFromIDList(
            IntPtr pidl,
            StringBuilder pszPath);



        /// <summary>
        /// Translates a Shell namespace object's display name into an item identifier list and returns the attributes
        /// of the object. This function is the preferred method to convert a string to a pointer to an item identifier
        ///  list (PIDL)
        /// </summary>
        /// <param name="pszName">Pointer to a zero-terminated wide string that contains the display name to parse.</param>
        /// <param name="pbc"> Optional bind context that controls the parsing operation. This parameter is normally
        ///  set to NULL.</param>
        /// <param name="ppidl">Address of a pointer to a variable of type ITEMIDLIST that receives the item identifier
        ///  list for the object.</param>
        /// <param name="sfgaoIn">ULONG value that specifies the attributes to query.</param>
        /// <param name="psfgaoOut">Pointer to a ULONG. On return, those attributes that are true for the object and
        ///  were requested in sfgaoIn will be set.</param>
        /// <returns></returns>
        [DllImport("shell32.dll")]
        public static extern Int32 SHParseDisplayName(
            [MarshalAs(UnmanagedType.LPWStr)]
			String pszName,
            IntPtr pbc,
            out IntPtr ppidl,
            UInt32 sfgaoIn,
            out UInt32 psfgaoOut);

        /// <summary>
        /// This function takes the fully-qualified pointer to an item identifier list (PIDL) of a namespace object,
        /// and returns a specified interface pointer on the parent object.
        /// </summary>
        /// <param name="pidl">The item's PIDL</param>
        /// <param name="riid">The REFIID of one of the interfaces exposed by the item's parent object</param>
        /// <param name="ppv">A pointer to the interface specified by riid. You must release the object when finished</param>
        /// <param name="ppidlLast">The item's PIDL relative to the parent folder</param>
        /// <returns>specified interface pointer on the parent object</returns>
        /// <remarks>The ppidlLast PIDL can be used with many of the methods supported by the parent folder's interfaces.
        ///  If you set ppidlLast to NULL, the PIDL will not be returned.</remarks>
        [DllImport("shell32.dll")]
        public static extern Int32 SHBindToParent(
            IntPtr pidl,
            [MarshalAs(UnmanagedType.LPStruct)]
			Guid riid,
            out IntPtr ppv,
            ref IntPtr ppidlLast);


        /// <summary>
        /// Accepts a STRRET structure returned by IShellFolder::GetDisplayNameOf that contains or points to a
        /// string, and then returns that string as a BSTR.
        /// </summary>
        /// <param name="pstr">Pointer to a STRRET structure.</param>
        /// <param name="pidl">Pointer to an ITEMIDLIST uniquely identifying a file object or subfolder relative
        /// to the parent folder.</param>
        /// <param name="pbstr">Pointer to a variable of type BSTR that contains the converted string.</param>
        /// <returns></returns>
        [DllImport("shlwapi.dll")]
        public static extern Int32 StrRetToBSTR(
            ref SHFILEINFO.STRRET pstr,
            IntPtr pidl,
            [MarshalAs(UnmanagedType.BStr)]
			out String pbstr);


        /// <summary>
        /// Takes a STRRET structure returned by IShellFolder::GetDisplayNameOf, converts it to a string, and
        /// places the result in a buffer.
        /// </summary>
        /// <param name="pstr">Pointer to the STRRET structure. When the function returns, this pointer will no
        /// longer be valid.</param>
        /// <param name="pidl">Pointer to the item's ITEMIDLIST structure.</param>
        /// <param name="pszBuf">Buffer to hold the display name. It will be returned as a null-terminated
        /// string. If cchBuf is too small, the name will be truncated to fit.</param>
        /// <param name="cchBuf">Size of pszBuf, in characters. If cchBuf is too small, the string will be truncated to fit.</param>
        /// <returns></returns>
        [DllImport("shlwapi.dll")]
        public static extern Int32 StrRetToBuf(
            ref SHFILEINFO.STRRET pstr,
            IntPtr pidl,
            StringBuilder pszBuf,
            UInt32 cchBuf);


        /// <summary>
        /// Performs an operation on a specified file.
        /// </summary>
        /// <param name="hwnd">Handle to a parent window.</param>
        /// <param name="lpOperation">Pointer to a null-terminated string, referred to in this case as a verb
        /// that specifies the action to be performed</param>
        /// <param name="lpFile">Pointer to a null-terminated string that specifies the file or object on which
        /// to execute the specified verb</param>
        /// <param name="lpParameters">If the lpFile parameter specifies an executable file, lpParameters is a pointer
        /// to a null-terminated string that specifies the parameters to be passed to the application</param>
        /// <param name="lpDirectory">Pointer to a null-terminated string that specifies the default directory</param>
        /// <param name="nShowCmd">Flags that specify how an application is to be displayed when it is opened</param>
        /// <returns>If the function succeeds, it returns a value greater than 32. If the function fails, it
        ///  returns an error value that indicates the cause of the failure</returns>
        [DllImport("shell32.dll")]
        public static extern IntPtr ShellExecute(
            IntPtr hwnd,
            [MarshalAs(UnmanagedType.LPStr)]
			String lpOperation,
            [MarshalAs(UnmanagedType.LPStr)]
			String lpFile,
            [MarshalAs(UnmanagedType.LPStr)]
			String lpParameters,
            [MarshalAs(UnmanagedType.LPStr)]
			String lpDirectory,
            Int32 nShowCmd);


        /// <summary>
        /// Performs an action on a file
        /// </summary>
        /// <param name="lpExecInfo">A pointer to a SHELLEXECUTEINFO structure that contains and receives
        ///  information about the application being executed</param>
        /// <returns>Returns TRUE if successful, or FALSE otherwise</returns>
        [DllImport("shell32.dll")]
        public static extern Int32 ShellExecuteEx(ref SHFILEINFO.SHELLEXECUTEINFO lpExecInfo);


        /// <summary>
        /// Notifies the system of an event that an application has performed. An application should use this function
        /// if it performs an action that may affect the Shell
        /// </summary>
        /// <param name="wEventId">Describes the event that has occurred. the ShellChangeNotificationEvents enum 
        /// contains a list of options</param>
        /// <param name="uFlags">Flags that indicate the meaning of the dwItem1 and dwItem2 parameters</param>
        /// <param name="dwItem1">First event-dependent value</param>
        /// <param name="dwItem2">Second event-dependent value</param>
        [DllImport("shell32.dll")]
        public static extern void SHChangeNotify(
            UInt32 wEventId,
            UInt32 uFlags,
            IntPtr dwItem1,
            IntPtr dwItem2);


        /// <summary>
        /// Adds a document to the Shell's list of recently used documents or clears all documents from the list.
        /// </summary>
        /// <param name="uFlags">Flag that indicates the meaning of the pv parameter</param>
        /// <param name="pv">A pointer to either a null-terminated string with the path and file name of the document,
        /// or a PIDL that identifies the document's file object. Set this parameter to NULL to clear all documents from the list.</param>
        [DllImport("shell32.dll")]
        public static extern void SHAddToRecentDocs(
            UInt32 uFlags,
            IntPtr pv);

        /// <summary>
        /// Notifies the system that an item has been accessed, for the purposes of tracking those items
        /// used most recently and most frequently. This function can also be used to clear all usage data.
        /// </summary>
        /// <param name="uFlags">A value from the SHARD enumeration that indicates the form of the 
        /// information pointed to by the pv parameter</param>
        /// <param name="pv">A pointer to data that identifies the item that has been accessed</param>
        [DllImport("shell32.dll")]
        public static extern void SHAddToRecentDocs(
            UInt32 uFlags,
            [MarshalAs(UnmanagedType.LPWStr)]
			String pv);


        /// <summary>
        /// Executes a command on a printer object
        /// </summary>
        /// <param name="hwnd">Handle of the window that will be used as the parent of any windows or dialog boxes that are
        ///  created during the operation</param>
        /// <param name="uAction">A value that determines the type of printer operation that will be performed</param>
        /// <param name="lpBuf1">Address of a null_terminated string that contains additional information for the printer command</param>
        /// <param name="lpBuf2">Address of a null-terminated string that contains additional information for the printer command</param>
        /// <param name="fModal">value that determines whether SHInvokePrinterCommand should return after initializing the command
        ///  or wait until the command is completed</param>
        /// <returns></returns>
        [DllImport("shell32.dll")]
        public static extern Int32 SHInvokePrinterCommand(
            IntPtr hwnd,
            UInt32 uAction,
            [MarshalAs(UnmanagedType.LPWStr)]
			String lpBuf1,
            [MarshalAs(UnmanagedType.LPWStr)]	
			String lpBuf2,
            Int32 fModal);


        /// <summary>
        /// The RegisterWindowMessage function defines a new window message that is guaranteed to be unique throughout
        ///  the system. The message value can be used when sending or posting messages
        /// </summary>
        /// <param name="lpString">Pointer to a null-terminated string that specifies the message to be registered</param>
        /// <returns>message successfully registered:  message identifier in range 0xC000 - 0xFFFF. 
        /// fails: zero</returns>
        [DllImport("user32.dll")]
        public static extern UInt32 RegisterWindowMessage(
            [MarshalAs(UnmanagedType.LPTStr)]
			String lpString);


        /// <summary>
        /// Sends an appbar message to the system
        /// </summary>
        /// <param name="dwMessage">Appbar message value to send</param>
        /// <param name="pData">The address of an APPBARDATA structure. The content of the structure on entry and on exit depends on the value set in the dwMessage parameter.</param>
        /// <returns>This function returns a message-dependent value</returns>
        [DllImport("shell32.dll")]
        public static extern UInt32 SHAppBarMessage(
            UInt32 dwMessage,
            ref SHFILEINFO.APPBARDATA pData);

        #endregion


        [DllImport("Shell32", CharSet = CharSet.Auto)]
        public static extern int ExtractIconEx(
            [MarshalAs(UnmanagedType.LPTStr)] string lpszFile,
            int nIconIndex,
            IntPtr[] phIconLarge,
            IntPtr[] phIconSmall,
            int nIcons);

        /// <summary>
        /// Destroys an icon and frees any memory the icon occupied
        /// </summary>
        /// <param name="hIcon">Handle to the icon to be destroyed. The icon must not be in use</param>
        /// <returns>succeeds: nonzero.  fails: zero.</returns>
        [DllImport("User32.dll")]
        public static extern int DestroyIcon(IntPtr hIcon);

        #region Nested type: IconHandler

        /// <summary>
        /// the function that will extract the icons from a file
        /// </summary>
        public class IconHandler
        {
            /// <summary>
            /// creates an array of handles to large or small icons extracted
            /// from the specified executable file, DLL, or icon file
            /// </summary>
            /// <param name="lpszFile">Pointer to a string specifying the name of a file from which icons will be extracted</param>
            /// <param name="nIconIndex">Specifies the zero-based index of the first icon to extract</param>
            /// <param name="phIconLarge">Pointer to the large (32x32) icon, or NULL for no large</param>
            /// <param name="phIconSmall">Pointer to the small (16x16) icon, or NULL for no small</param>
            /// <param name="nIcons">number of icons to extract from the file</param>
            /// <returns>If the nIconIndex parameter is -1, the phiconLarge parameter is NULL, and the phiconSmall 
            /// parameter is NULL, then the return value is the number of icons contained in the specified file. Otherwise,
            ///  the return value is the number of icons successfully extracted from the file</returns>







        }

        #endregion
    }
}